package org.zjvis.datascience.common.graph.filter;

import lombok.Data;
import org.zjvis.datascience.common.dto.graph.GraphFilterDTO;
import org.zjvis.datascience.common.graph.enums.GraphFilterSubTypeEnum;

import java.util.*;

/**
 * @description FilterTree
 * @date 2021-12-29
 */
@Data
public class FilterTree {
    public FilterTreeNode<Long> root;
    public Stack<List<Long>> pathStack;
    private Map<Long, GraphFilterDTO> filterMap;

    public static Long OR_VALUE = -1L;
    public static Long AND_VALUE = -2L;


    public FilterTree(FilterTreeNode<Long> root, Map<Long, GraphFilterDTO> filterMap) {
        this.root = root;
        this.pathStack = new Stack<>();
        this.filterMap = filterMap;
    }

    public void dfs() {
        List<Long> path = new ArrayList<>();
        path.add(root.value);
        this.findPath(root, path);
    }

    private void findPath(FilterTreeNode<Long> node, List<Long> path) {
        if (node.children == null || node.children.size() <= 0) {
            pathStack.push(path);
            return;
        }
        int subType = filterMap.get(node.value).getSubType();
        if (subType == GraphFilterSubTypeEnum.OPERATION_AND.getVal()) {
            List<Long> opPath = new ArrayList<>();
            for (int i = 0; i < node.children.size(); i++) {
                opPath.add(AND_VALUE);
            }
            pathStack.push(opPath);
        }
        if (subType == GraphFilterSubTypeEnum.OPERATION_OR.getVal()) {
            List<Long> opPath = new ArrayList<>();
            for (int i = 0; i < node.children.size(); i++) {
                opPath.add(OR_VALUE);
            }
            pathStack.push(opPath);
        }
        for (int i = 0; i < node.children.size(); i++) {
            FilterTreeNode<Long> child = node.children.get(i);
            List<Long> cPath = new ArrayList<>(path);
            cPath.add(child.value);
            findPath(child, cPath);
        }
    }
}
